package com.zyf.service.img;

import cn.hutool.core.io.FileUtil;
import com.zyf.utils.FFmpegUtils;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


public class ImageHandle {

    //按质量压缩
    public static void compressImg() throws Exception {
        Thumbnails.of(new File("D:/showqrcode.jpg"))
                .scale(1f) //图片大小（长宽）压缩比例 从0-1，1表示原图
                .outputQuality(0.5f) //图片质量压缩比例 从0-1，越接近1质量越好
                .toOutputStream(new FileOutputStream("D:/showqrcode_50.jpg"));
    }


    // 按比例缩放
    public static void zoomByRatio() throws Exception {
        Thumbnails.of(new File("D:/showqrcode.jpg"))
                .scale(0.5f) //图片大小（长宽）压缩 从0按照
                .outputQuality(0.5f) //图片质量压缩比例 从0-1，越接近1质量越好
                .toOutputStream(new FileOutputStream("D:/showqrcode_50%.jpg"));
    }

    //按大小和比例缩放
    public static void zoomBySizeandratio(String srcPath) throws Exception {
        String outpath=srcPath.replace(".","_final.");
        Thumbnails.of(new File(srcPath))
                .size(1300, 900) // 图片比例不变
                .toOutputStream(new FileOutputStream(outpath));
    }

    // 按大小缩放
    public static void zoomBySize(String srcPath) throws Exception {
        String outpath=srcPath.replace(".","_final.");
        Thumbnails.of(new File(srcPath))
                .forceSize(900, 1300) //不保持图片比例
                .toOutputStream(new FileOutputStream(outpath));
    }

    // 旋转
    public static void rotateImg() throws Exception {
        Thumbnails.of(new File("D:/showqrcode.jpg"))
                .forceSize(500, 300)
                .rotate(90f) //向右旋转
                .toOutputStream(new FileOutputStream("D:/showqrcode+90.jpg"));
    }

    //加水印
    public static void addWatermark() throws IOException {
        Thumbnails.of("D:/showqrcode.jpg")
                .size(1280, 1024)
                .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("D:/watermark.jpg")),
                        0.5f) //位置，水印来源，透明度
                .outputQuality(0.8f)
                .toFile("D:/showqrcode_watermark_bottom_right.jpg");
    }


    //裁剪
    public static void cuttingImg(String srcPath) throws IOException {
        String outpath=srcPath.replace(".","_final.");
        Thumbnails.of(srcPath)
                .sourceRegion(Positions.CENTER, 900, 1600) //位置，宽，高
                .size(900, 1600)
                .keepAspectRatio(false)
                .toFile(outpath);
    }

    // 拼接
    public static void splicingImg() throws Exception {
        byte[] bytes = joinImages(false, new File("D:/showqrcode.jpg"), new File("D:/showqrcode.jpg"));
        if (Objects.nonNull(bytes)) {
//            new ByteArrayInputStream(bytes).transferTo(new FileOutputStream("D:/showqrcode_join.jpg"));


        }
    }

    /**
     * 将多张图片拼接成一张
     *
     * @param horizontal 是否为水平拼接
     * @param files      文件列表
     * @return 拼接后的文件字节数组
     */
    private static byte[] joinImages(boolean horizontal, File... files) throws IOException {
        if (Objects.isNull(files) || files.length == 0) {
            return null;
        }
        List<BufferedImage> imageList = new ArrayList<>();
        for (File file : files) {
            BufferedImage image = ImageIO.read(file);
            imageList.add(image);
        }
        int height = imageList.get(0).getHeight();
        int width = imageList.get(0).getWidth();
        if (horizontal) {
            width = imageList.stream().mapToInt(BufferedImage::getWidth).sum();
        } else {
            height = imageList.stream().mapToInt(BufferedImage::getHeight).sum();
        }
        //创建拼接后的图片画布，参数分别为宽，高，类型，这里我们使用RGB3元色类型
        BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = resultImage.getGraphics();
        int previousWidth = 0;
        int previousHeight = 0;
        for (BufferedImage image : imageList) {
            //向画布上画图片
            graphics.drawImage(image, previousWidth, previousHeight, null);
            if (horizontal) {
                previousWidth += image.getWidth();
            } else {
                previousHeight += image.getHeight();
            }
        }
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(resultImage, "jpg", output);
        return output.toByteArray();
    }

    /**
     * 修改图片像素尺寸
     *
     * @throws Exception
     */
    public static void ImagePixelModifier(String srcpath) throws Exception {
        // 读取图片
        BufferedImage image = ImageIO.read(new File(srcpath));
        //获取图片的像素数组
        int width = image.getWidth();
        int height = image.getHeight();
        int[] pixels = image.getRGB(0, 0, width, height, null, 0, width);
        //修改像素数组中的像素值
        for (int i = 0; i < pixels.length; i++) {
            int pixel = pixels[i];

            // 从像素值中获取红、绿、蓝和透明度分量
            int alpha = (pixel >> 24) & 0xFF;
            int red = (pixel >> 16) & 0xFF;
            int green = (pixel >> 8) & 0xFF;
            int blue = pixel & 0xFF;

            // 修改分量的值
            red = 255 - red; // 将红色分量取反

            // 将修改后的分量重新合成为像素值
            pixel = (alpha << 24) | (red << 16) | (green << 8) | blue;

            // 更新像素数组
            pixels[i] = pixel;
        }
        //将修改后的像素数组重新写入图片
        image.setRGB(0, 0, width, height, pixels, 0, width);
        //保存修改后的图片
        String despath = srcpath;

        ImageIO.write(image, "jpg", new File(despath));

    }

    /**
     * @param srcPath 原图片路径
     *                批量调整图片尺寸
     * @param width   转换后图片宽度
     * @param height  转换后图片高度
     */
    public static void resizeImage(String srcPath,
                                   int width, int height) throws IOException {
        List<File> files = FileUtil.loopFiles(srcPath, file -> file.isFile() && (file.getName().contains(".jpg") || file.getName().contains(".png")));
        for (File imgFile : files) {
            Image srcImg = ImageIO.read(imgFile);
            BufferedImage buffImg = null;
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //使用TYPE_INT_RGB修改的图片会变色
            buffImg.getGraphics().drawImage(
                    srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0,
                    0, null);
            String desPath = imgFile.getAbsolutePath().substring(0, imgFile.getAbsolutePath().indexOf(".")) + "重置" + ".jpg";
            ImageIO.write(buffImg, "jpg", new File(desPath));
        }
    }

    /**
     * @param srcPath 原图片路径
     *                调整单个图片尺寸
     * @param width   转换后图片宽度
     *                ffmpeg -i moon.jpg -vf "scale=h=1600" output.jpg
     * @param height  转换后图片高度
     */
    public static String resizeSingleImage(String srcPath,
                                         int width, int height) throws Exception {
        String outpath=srcPath.replace(".","_final.");
        List<String> commands = new ArrayList<>();
        commands.add("ffmpeg");
        commands.add("-i");
        commands.add(srcPath);
        commands.add("-vf");
        commands.add("\"scale=scale=1300:1600\"");
        commands.add(outpath);

        String result= FFmpegUtils.execFFmpegCommand(commands);
        System.out.println(result);
        return outpath;
    }






}
